﻿using Fidely.Framework;
using Sasa.QualityTools.CodeAnalysis.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels
{
    public class MetricValueViewModel : ViewModelBase, ICodeAnalysisResultRowViewModel
    {
        private MetricValue model;

        private string projectName;


        [Rename("kind")]
        [Description("Kind of target.")]
        [Alias("k", Description = "Alias name of 'kind'")]
        public string Kind
        {
            get
            {
                var v = Enum.GetName(typeof(CodeKind), model.Kind);
                return v;
            }
            set
            {
                model.Kind = (CodeKind)Enum.Parse(typeof(CodeKind), value);
                OnPropertyChanged("Kind");
            }
        }

        [Rename("name")]
        [Description("Target name")]
        [Alias("n", Description = "Alias name of 'name'")]
        public string Name
        {
            get
            {
                switch (model.Kind)
                {
                    case CodeKind.Module:
                        return AssemblyName;
                    case CodeKind.Namespace:
                        return model.Namespace;
                    case CodeKind.Type:
                        return model.TypeName;
                    case CodeKind.Member:
                        return model.Signature;
                    default:
                        return null;
                }
            }
        }

        [NotEvaluate]
        public string AssemblyPath
        {
            get
            {
                return model.AssemblyPath;
            }
            set
            {
                model.AssemblyPath = value;
                OnPropertyChanged("AssemblyPath");
            }
        }

        [Rename("namespace")]
        [Description("Namespace of target.")]
        [Alias("ns", Description = "Alias name of 'namespace'")]
        public string Namespace
        {
            get
            {
                return model.Namespace;
            }
            set
            {
                model.Namespace = value;
                OnPropertyChanged("Namespace");
            }
        }

        [Rename("type")]
        [Description("Type name of target.")]
        [Alias("t", Description = "Alias name of 'type'")]
        public string TypeName
        {
            get
            {
                return model.TypeName;
            }
            set
            {
                model.TypeName = value;
                OnPropertyChanged("TypeName");
            }
        }

        [Rename("signature")]
        [Description("Signature of target.")]
        [Alias("sig", Description = "Alias name of 'signature'")]
        public string Signature
        {
            get
            {
                return model.Signature;
            }
            set
            {
                model.Signature = value;
                OnPropertyChanged("Signature");
            }
        }

        [Rename("mi")]
        [Description("Maintainability index")]
        public int MaintainabilityIndex
        {
            get
            {
                return model.MaintainabilityIndex;
            }
            set
            {
                model.MaintainabilityIndex = value;
                OnPropertyChanged("MaintainabilityIndex");
            }
        }

        [Rename("cc")]
        [Description("Cyclomatic complexity")]
        public int CyclomaticComplexity
        {
            get
            {
                return model.CyclomaticComplexity;
            }
            set
            {
                model.CyclomaticComplexity = value;
                OnPropertyChanged("CyclomaticComplexity");
            }
        }

        [Rename("ccp")]
        [Description("Class coupling")]
        public int ClassCoupling
        {
            get
            {
                return model.ClassCoupling;
            }
            set
            {
                model.ClassCoupling = value;
                OnPropertyChanged("ClassCoupling");
            }
        }

        [Rename("loc")]
        [Description("Lines of Code")]
        public int LinesOfCode
        {
            get
            {
                return model.LinesOfCode;
            }
            set
            {
                model.LinesOfCode = value;
                OnPropertyChanged("LineOfCode");
            }
        }

        [Rename("doi")]
        [Description("Depth of Inheritance")]
        public int? DepthOfInheritance
        {
            get
            {
                return model.DepthOfInheritance;
            }
            set
            {
                model.DepthOfInheritance = value;
                OnPropertyChanged("DepthOfInheritance");
            }
        }

        [NotEvaluate]
        public string Path
        {
            get
            {
                return model.Path;
            }
            set
            {
                model.Path = value;
                OnPropertyChanged("Path");
            }
        }

        [NotEvaluate]
        public int? Line
        {
            get
            {
                return model.Line;
            }
            set
            {
                model.Line = value;
                OnPropertyChanged("Line");
            }
        }

        [Rename("project")]
        [Description("Project Name")]
        [Alias("p", Description = "Alias name of 'project'")]
        public string ProjectName
        {
            get
            {
                return projectName;
            }
            set
            {
                projectName = value;
                OnPropertyChanged("ProjectName");
            }
        }

        [Rename("assembly")]
        [Description("Assembly Name")]
        [Alias("asm", Description = "Alias name of 'assembly'")]
        public string AssemblyName
        {
            get
            {
                return (!String.IsNullOrWhiteSpace(model.AssemblyPath)) ? System.IO.Path.GetFileNameWithoutExtension(model.AssemblyPath) : String.Empty;
            }
        }

        [NotEvaluate]
        public bool CanFocusSourceCode
        {
            get
            {
                return File.Exists(Path) && Line.HasValue;
            }
        }


        public MetricValueViewModel(MetricValue model)
        {
            this.model = model;
        }
    }
}
